/*******************************************************************************
  * 文件：BoardCommC7.c
  * 作者：djy
  * 版本：v1.0.0
  * 日期：2019-05-15
  * 说明: 显示板与电源板C7通信协议，C7协议为海尔内部协议
*******************************************************************************/
#include "BoardCommC7.h"
#include "DevInfor.h"
#include "DevCtrl.h"
#include "CRC.h"
#include "ComFun.h"

#if CONFIG_BOARDCOMM_C7

static BoardCommCtrl_ts sBoardCommCtrl;

static BoardFrame_ts* BoardCommRecvFrameCheck(U8 au8Data[],U8 u8len)
{
    U8 i = 0;
    U8 j = 0;
    U8 k = 0;
    
check:
    while(i<u8len)
    {
        if(au8Data[i] == u8BOARD_COMM_C7_FRAME_STX 
            && au8Data[i+1] == u8BOARD_COMM_C7_FRAME_STX)
        {
            // 寻找帧头
            break;
        }
        
        i++;
    }

    if(i >= u8len)
    {
        return NULL;
    }
    
    U8 au8Frame[u8BOARD_COMM_C7_FRAME_MAX_LEN];

    // 将报文中的转义冗余字符0x55去除
    for(j=0,k=0;j<u8len-i;j++)
    {
        au8Frame[j] = au8Data[i+j+k];

        if(j>=2 && au8Data[i+j+k] == u8BOARD_COMM_C7_FRAME_STX
                && au8Data[i+j+k+1] == u8BOARD_COMM_C7_FRAME_SURPLUS )
        {
            k++;
        }
    }

    BoardFrame_ts *psFrame = (BoardFrame_ts *)au8Frame;

    // 目的地址不对
    if(u8BOARD_COMM_C7_FRAME_DISPLAY_ADDR != Get_BigEndian_Value(psFrame->au8DestAddr,3))
    {
        i++;
        goto check;
    }

    // 源地址不对
    if(u8BOARD_COMM_C7_FRAME_POWER_ADDR != Get_BigEndian_Value(psFrame->au8SourceAddr,3))
    {
        i++;
        goto check;
    }

    // 校验错误
    if(psFrame->au8Data[psFrame->u8Len-9] != CRC_CalcCRC8(&(psFrame->u8Len),psFrame->u8Len,0))
    {
        i++;
        goto check;
    }

    // 合法报文，返回指针
    return psFrame;
}

static void BoardCommRecvFrameTask(U32 arg)
{
    U8 au8Data[255];
    
    // 从接收缓冲区取出数据
    U8 u8Len = UartRxFIFOPeek(UART5_CHN,au8Data,sizeof (au8Data));

    if(u8Len)
    {
        // 校验数据是否为合法报文
        BoardFrame_ts *psBoardFrame = BoardCommRecvFrameCheck(au8Data,u8Len); 

        if(psBoardFrame != NULL)
        {
            // 合法报文，获取数据域
            BoardRecvData_ts *psRecvData = (BoardRecvData_ts *)(psBoardFrame->au8Data);

            U16 u16CMD = ((((U16)(psBoardFrame->u8Cmd_H))<<8) + psBoardFrame->u8Cmd_L);
            
            if(u16CMD == u16BOARD_COMM_C7_UPWARD)
            {
                // 上行CMD，更新状态
                Dev_SetDoorStatus(psRecvData->bDoorStatus);
                Dev_SetWaterBoxStatus(psRecvData->bWaterBoxStatus);
                Dev_SetSteamPanWaterStatus(psRecvData->bSteamPanWaterStatus);
                Dev_SetCavityTemper(((((U16)(psRecvData->u8CavitySensor_H))<<8) + psRecvData->u8CavitySensor_L));
                Dev_SetSteamGeneratorTemper(((((U16)(psRecvData->u8SteamGeneratorSensor_H))<<8) + psRecvData->u8SteamGeneratorSensor_H));
                Dev_SetBottomTemper(((((U16)(psRecvData->u8BottomSensor_H))<<8) + psRecvData->u8BottomSensor_L));
            }
            // 清空缓冲区
            SerialRxBuffClear(eSERIAL_CHN0,(&(psBoardFrame->au8Data[psBoardFrame->u8Len-9])-au8Data));
        }
        else
        {
            // 非法报文
            if(u8Len > 200)
            {
                // 非法数据过多，清空缓冲区
                SerialRxBuffClear(eSERIAL_CHN0,u8Len);
            }
        }
    }
}

void BoardCommSendCtrlFrame(void)
{

}

static void BoardCommHandlerHook_100MS(void)
{
    // 发送控制报文
    BoardCommSendCtrlFrame();
}

void BoardCommC7_Init(void)
{
    // 创建解析任务
    Task_AddTask(BoardCommRecvFrameTask,0);
    // 启动定时器
    Timer_Start(&(sBoardCommCtrl.sTimer),
                  100,
                  BoardCommHandlerHook_100MS,
                  TRUE);
    
}

#endif

